home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Printing / STD File Saver 2.0 / Source / MyPDEF_0_DraftMode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-08  |  22.4 KB  |  862 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Copyright 1991-1996 Apple Computer. All rights reserved.
  3. **
  4. **    You may incorporate this sample code into your applications without
  5. **    restriction, though the sample code has been provided "AS IS" and the
  6. **    responsibility for its operation is 100% yours.  However, what you are
  7. **    not permitted to do is to redistribute the source as "DSC Sample Code"
  8. **    after having made changes. If you're going to re-distribute the source,
  9. **    we require that you make it clear in the source that the code was
  10. **    descended from Apple Sample Code, but that you've made changes.
  11. */
  12.  
  13. #include <stddef.h>
  14. #include <types.h>
  15.  
  16. #include <Printing.h>
  17. #include <Memory.h>
  18. #include <Files.h>
  19. #include <Resources.h>
  20. #include <TextUtils.h>
  21. #include <StandardFile.h>
  22. #include <Events.h>
  23.  
  24. #include "driverTypes.h"
  25. #include "StringUtils.h"
  26.  
  27.  
  28. /*******************************************************************************
  29.     Constants for the Command-period checker.
  30. *******************************************************************************/
  31. #define    kModifiersMask        0xFF00 & ~cmdKey    /*    We need all modifiers
  32.                                                     except the command key
  33.                                                     for KeyTrans. */
  34. #define    kOtherCharCodeMask    0x00FF0000            /*    Get the key out of the
  35.                                                     ASCII1 byte. */
  36.  
  37. static Boolean IsColorGrafPort(GrafPtr thePort)
  38. {
  39.     return(thePort->portBits.rowBytes < 0);
  40. }
  41.  
  42. static void GetEventChars(EventRecord *theEvent, long *lowChar, long *highChar)
  43. {
  44.     unsigned    long    state = 0;
  45.     long                keyInfo;
  46.     long                virtualKey = (theEvent->message & keyCodeMask) >> 8;
  47.     long                keyCID    = GetScript(GetEnvirons(smKeyScript), smScriptKeys);
  48.     Handle                hKCHR    = GetResource('KCHR', keyCID);
  49.     unsigned    short    keyCode    = (theEvent->modifiers & kModifiersMask) | virtualKey;
  50.  
  51.     if (hKCHR != nil) {
  52.         HLock(hKCHR);
  53.         keyInfo = KeyTranslate((void *)(*hKCHR), keyCode, &state);
  54.         HUnlock(hKCHR);
  55.         ReleaseResource( hKCHR );
  56.     } else {
  57.         keyInfo = theEvent->message;
  58.     }
  59.  
  60.     *lowChar =  keyInfo & charCodeMask;
  61.     *highChar = (keyInfo & kOtherCharCodeMask) >> 16;
  62. }
  63.  
  64. static Boolean CmdPeriod(EventRecord *theEvent)
  65. {
  66.     Boolean  result;
  67.  
  68.     if ((theEvent->what == keyDown) || (theEvent->what == autoKey)) {
  69.         long    lowChar, highChar;
  70.         GetEventChars(theEvent, &lowChar, &highChar);
  71.  
  72.         if ((theEvent->modifiers & cmdKey) != 0 ) {
  73.             result = ((lowChar == period) || (highChar == period));
  74.         } else {
  75.             result = ((lowChar == escape) || (highChar == escape));
  76.         }
  77.     } else result = false;    // it wasn't my kind of event
  78.  
  79.     return result;
  80. }
  81.  
  82. static void MyIdleProc(void)
  83. {
  84.     const short mask = (keyDownMask | autoKeyMask);
  85.     EventRecord    theEvent;
  86.     
  87.     if (EventAvail(mask,&theEvent)) {
  88.         if (CmdPeriod(&theEvent)) {
  89.             (void)GetNextEvent(mask,&theEvent);    // eat the event
  90.             setPrintErr(iPrAbort);
  91.         }
  92.     }
  93. }
  94.  
  95. static void CallIdleProc(PrIdleUPP idleProc)
  96. {
  97.     if (idleProc)
  98.         CallPrIdleProc(idleProc);
  99.     else
  100.         MyIdleProc();
  101. }
  102.  
  103. pascal void DraftPrText(short byteCount, Ptr textBuf, Point numer, Point denom)
  104. {
  105. #pragma unused(numer)
  106. #pragma unused(denom)
  107.  
  108.     GrafPtr pPrPort;
  109.     MyPrintPtr myPrintRecord;
  110.  
  111. #ifdef TRACKING
  112.     DebugStr("\pin DraftPrText;g");
  113. #endif
  114.  
  115.     GetPort(&pPrPort);
  116.  
  117.     // don't need to worry about rgnSave or polySave for text
  118.  
  119.     myPrintRecord = (MyPrintPtr)(((TPPrPort)pPrPort)->lGParam4);
  120.  
  121.     BlockMove(pPrPort, myPrintRecord->OtherPort, mostOfGrafPort);
  122.     SetPort(myPrintRecord->OtherPort);
  123.     // do scaling here
  124.     DrawText(textBuf, 0, byteCount);
  125.     CallIdleProc(myPrintRecord->idleProc);
  126.     SetPort(pPrPort);
  127.     // adjust the pen location for scaling
  128. }
  129.  
  130. pascal void DraftPrLine(Point newPt)
  131. {
  132.     GrafPtr pPrPort;
  133.     MyPrintPtr printRecord;
  134.  
  135. #ifdef TRACKING
  136.     DebugStr("\pin DraftPrLine;g");
  137. #endif
  138.  
  139.     GetPort(&pPrPort);
  140.  
  141.     printRecord = (MyPrintPtr)(((TPPrPort)pPrPort)->lGParam4);
  142.  
  143.     // if rgnSave field of grafPort is non-nil, don't change port,
  144.     // since that screws up region recording, same goes for polySave
  145.     if ((pPrPort->rgnSave) || (pPrPort->polySave)) {
  146.         StdLine(newPt);
  147.     } else {
  148.         BlockMove(pPrPort, printRecord->OtherPort, mostOfGrafPort);
  149.         SetPort(printRecord->OtherPort);
  150.         // do scaling here
  151.         LineTo(newPt.h, newPt.v);
  152.         SetPort(pPrPort);
  153.         pPrPort->pnLoc = newPt;    // set the pen location correctly
  154.     }
  155.     CallIdleProc(printRecord->idleProc);
  156. }
  157.  
  158. pascal void DraftPrRect(GrafVerb verb, RectPtr r)
  159. {
  160.     GrafPtr pPrPort;
  161.     MyPrintPtr printRecord;
  162.  
  163. #ifdef TRACKING
  164.     DebugStr("\pin DraftPrRect;g");
  165. #endif
  166.  
  167.     GetPort(&pPrPort);
  168.  
  169.     printRecord = (MyPrintPtr)(((TPPrPort)pPrPort)->lGParam4);
  170.  
  171.     // if rgnSave field of grafPort is non-nil, don't change port,
  172.     // since that screws up region recording, same goes for polySave
  173.     if ((pPrPort->rgnSave) || (pPrPort->polySave)) {
  174.         StdRect(verb,r);
  175.     } else {
  176.         BlockMove(pPrPort, printRecord->OtherPort, mostOfGrafPort);
  177.         SetPort(printRecord->OtherPort);
  178.         // do scaling here
  179.         switch (verb) { 
  180.             case frame:
  181.                 FrameRect(r);
  182.                 break;
  183.             case paint:
  184.                 PaintRect(r);
  185.                 break;
  186.             case erase:
  187.                 EraseRect(r);
  188.                 break;
  189.             case invert:
  190.                 InvertRect(r);
  191.                 break;
  192.             case fill:
  193.                 FillRect(r, &printRecord->OtherPort->fillPat);
  194.                 break;
  195.             default:
  196.                 DebugStr("\pUnknown verb for rect");
  197.                 break;
  198.         }
  199.         SetPort(pPrPort);
  200.     }
  201.     CallIdleProc(printRecord->idleProc);
  202. }
  203.  
  204. pascal void DraftPrrRect(GrafVerb verb, Rect * r, short ovalWidth, short ovalHeight)
  205. {
  206.     GrafPtr pPrPort;
  207.     MyPrintPtr printRecord;
  208.  
  209. #ifdef TRACKING
  210.     DebugStr("\pin DraftPrrRect;g");
  211. #endif
  212.  
  213.     GetPort(&pPrPort);
  214.  
  215.     printRecord = (MyPrintPtr)(((TPPrPort)pPrPort)->lGParam4);
  216.  
  217.     // if rgnSave field of grafPort is non-nil, don't change port,
  218.     // since that screws up region recording, same goes for polySave
  219.     if ((pPrPort->rgnSave) || (pPrPort->polySave)) {
  220.         StdRRect(verb,r,ovalWidth,ovalHeight);
  221.     } else {
  222.         BlockMove(pPrPort, printRecord->OtherPort, mostOfGrafPort);
  223.         SetPort(printRecord->OtherPort);
  224.         // do scaling here
  225.         switch (verb) { 
  226.             case frame:
  227.                 FrameRoundRect(r, ovalWidth, ovalHeight);
  228.                 break;
  229.             case paint:
  230.                 PaintRoundRect(r, ovalWidth, ovalHeight);
  231.                 break;
  232.             case erase:
  233.                 EraseRoundRect(r, ovalWidth, ovalHeight);
  234.                 break;
  235.             case invert:
  236.                 InvertRoundRect(r, ovalWidth, ovalHeight);
  237.                 break;
  238.             case fill:
  239.                 FillRoundRect(r, ovalWidth, ovalHeight, &printRecord->OtherPort->fillPat);
  240.                 break;
  241.             default:
  242.                 DebugStr("\pUnknown verb for RoundRect");
  243.                 break;
  244.         }
  245.         SetPort(pPrPort);
  246.     }
  247.     CallIdleProc(printRecord->idleProc);
  248. }
  249.  
  250. pascal void DraftPrOval(GrafVerb verb, Rect * r)
  251. {
  252.     GrafPtr pPrPort;
  253.     MyPrintPtr printRecord;
  254.  
  255. #ifdef TRACKING
  256.     DebugStr("\pin DraftPrOval;g");
  257. #endif
  258.  
  259.     GetPort(&pPrPort);
  260.  
  261.     printRecord = (MyPrintPtr)(((TPPrPort)pPrPort)->lGParam4);
  262.  
  263.     // if rgnSave field of grafPort is non-nil, don't change port,
  264.     // since that screws up region recording, same goes for polySave
  265.     if ((pPrPort->rgnSave) || (pPrPort->polySave)) {
  266.         StdOval(verb,r);
  267.     } else {
  268.         BlockMove(pPrPort, printRecord->OtherPort, mostOfGrafPort);
  269.         SetPort(printRecord->OtherPort);
  270.         // do scaling here
  271.         switch (verb) { 
  272.             case frame:
  273.                 FrameOval(r);
  274.                 break;
  275.             case paint:
  276.                 PaintOval(r);
  277.                 break;
  278.             case erase:
  279.                 EraseOval(r);
  280.                 break;
  281.             case invert:
  282.                 InvertOval(r);
  283.                 break;
  284.             case fill:
  285.                 FillOval(r, &printRecord->OtherPort->fillPat);
  286.                 break;
  287.             default:
  288.                 DebugStr("\pUnknown verb for oval");
  289.                 break;
  290.         }
  291.         SetPort(pPrPort);
  292.     }
  293.     CallIdleProc(printRecord->idleProc);
  294. }
  295.  
  296. pascal void DraftPrArc(GrafVerb verb, Rect * r, short startAngle, short arcAngle)
  297. {
  298.     GrafPtr pPrPort;
  299.     MyPrintPtr printRecord;
  300.  
  301. #ifdef TRACKING
  302.     DebugStr("\pin DraftPrArc;g");
  303. #endif
  304.  
  305.     GetPort(&pPrPort);
  306.  
  307.     printRecord = (MyPrintPtr)(((TPPrPort)pPrPort)->lGParam4);
  308.  
  309.     // if rgnSave field of grafPort is non-nil, don't change port,
  310.     // since that screws up region recording, same goes for polySave
  311.     if ((pPrPort->rgnSave) || (pPrPort->polySave)) {
  312.         StdArc(verb,r,startAngle,arcAngle);
  313.     } else {
  314.         BlockMove(pPrPort, printRecord->OtherPort, mostOfGrafPort);
  315.         SetPort(printRecord->OtherPort);
  316.         // do scaling here
  317.         switch (verb) { 
  318.             case frame:
  319.                 FrameArc(r, startAngle, arcAngle);
  320.                 break;
  321.             case paint:
  322.                 PaintArc(r, startAngle, arcAngle);
  323.                 break;
  324.             case erase:
  325.                 EraseArc(r, startAngle, arcAngle);
  326.                 break;
  327.             case invert:
  328.                 InvertArc(r, startAngle, arcAngle);
  329.                 break;
  330.             case fill:
  331.                 FillArc(r, startAngle, arcAngle, &printRecord->OtherPort->fillPat);
  332.                 break;
  333.             default:
  334.                 DebugStr("\pUnknown verb for arc");
  335.                 break;
  336.         }
  337.         SetPort(pPrPort);
  338.     }
  339.     CallIdleProc(printRecord->idleProc);
  340. }
  341.  
  342. pascal void DraftPrPoly(GrafVerb verb, PolyHandle Poly)
  343. {
  344.     GrafPtr pPrPort;
  345.     MyPrintPtr printRecord;
  346.  
  347. #ifdef TRACKING
  348.     DebugStr("\pin DraftPrPoly;g");
  349. #endif
  350.  
  351.     GetPort(&pPrPort);
  352.  
  353.     printRecord = (MyPrintPtr)(((TPPrPort)pPrPort)->lGParam4);
  354.  
  355.     // if rgnSave field of grafPort is non-nil, don't change port,
  356.     // since that screws up region recording
  357.     // calling poly procs with poly recording on is bad, so we won't
  358.     // even think about that possibility
  359.     if (pPrPort->rgnSave) {
  360.         StdPoly(verb,Poly);
  361.     } else {
  362.         BlockMove(pPrPort, printRecord->OtherPort, mostOfGrafPort);
  363.         SetPort(printRecord->OtherPort);
  364.         // do scaling here
  365.         switch (verb) { 
  366.             case frame:
  367.                 FramePoly(Poly);
  368.                 break;
  369.             case paint:
  370.                 PaintPoly(Poly);
  371.                 break;
  372.             case erase:
  373.                 ErasePoly(Poly);
  374.                 break;
  375.             case invert:
  376.                 InvertPoly(Poly);
  377.                 break;
  378.             case fill:
  379.                 FillPoly(Poly, &printRecord->OtherPort->fillPat);
  380.                 break;
  381.             default:
  382.                 DebugStr("\pUnknown verb for poly");
  383.                 break;
  384.         }
  385.         SetPort(pPrPort);
  386.     }
  387.     CallIdleProc(printRecord->idleProc);
  388. }
  389.  
  390. pascal void DraftPrRgn(GrafVerb verb, RgnHandle Rgn)
  391. {
  392.     GrafPtr pPrPort;
  393.     MyPrintPtr printRecord;
  394.  
  395. #ifdef TRACKING
  396.     DebugStr("\pin DraftPrRgn;g");
  397. #endif
  398.  
  399.     GetPort(&pPrPort);
  400.  
  401.     printRecord = (MyPrintPtr)(((TPPrPort)pPrPort)->lGParam4);
  402.  
  403.     // if rgnSave field of grafPort is non-nil, don't change port,
  404.     // since that screws up region recording, same goes for polySave
  405.     // calling poly procs with poly recording on would be
  406.     // bad enough that I'm just going to ignore it.
  407.     if (pPrPort->polySave) {
  408.         StdRgn(verb,Rgn);
  409.     } else {
  410.         BlockMove(pPrPort,printRecord->OtherPort, mostOfGrafPort);
  411.         SetPort(printRecord->OtherPort);
  412.         // do scaling here
  413.         switch (verb) { 
  414.             case frame:
  415.                 FrameRgn(Rgn);
  416.                 break;
  417.             case paint:
  418.                 PaintRgn(Rgn);
  419.                 break;
  420.             case erase:
  421.                 EraseRgn(Rgn);
  422.                 break;
  423.             case invert:
  424.                 InvertRgn(Rgn);
  425.                 break;
  426.             case fill:
  427.                 FillRgn(Rgn, &printRecord->OtherPort->fillPat);
  428.                 break;
  429.             default:
  430.                 DebugStr("\pUnknown region verb");
  431.                 break;
  432.         }
  433.         SetPort(pPrPort);
  434.     }
  435.     CallIdleProc(printRecord->idleProc);
  436. }
  437.  
  438. pascal void DraftPrBits(BitMapPtr srcBits, Rect * srcRect, Rect * dstRect, short mode, RgnHandle maskRgn)
  439. {
  440.     GrafPtr pPrPort;
  441.     Rect aRect;
  442.     MyPrintPtr printRecord;
  443.  
  444. #ifdef TRACKING
  445.     DebugStr("\pin DraftPrBits;g");
  446. #endif
  447.  
  448.     GetPort(&pPrPort);
  449.  
  450.     printRecord = (MyPrintPtr)(((TPPrPort)pPrPort)->lGParam4);
  451.  
  452.     BlockMove(pPrPort, printRecord->OtherPort, mostOfGrafPort);
  453.     SetPort(printRecord->OtherPort);
  454.     aRect = *dstRect;
  455.     // do scaling here
  456.     CopyBits(srcBits, &printRecord->OtherPort->portBits, srcRect, &aRect, mode, maskRgn);
  457.     CallIdleProc(printRecord->idleProc);
  458.     SetPort(pPrPort);
  459. }
  460.  
  461. pascal void DraftPrComment(short kind, short dataSize, Handle dataHandle)
  462. {
  463.     GrafPtr pPrPort;
  464.     MyPrintPtr printRecord;
  465.  
  466. #ifdef TRACKING
  467.     DebugStr("\pin DraftPrComment;g");
  468. #endif
  469.  
  470.     GetPort(&pPrPort);
  471.  
  472.     printRecord = (MyPrintPtr)(((TPPrPort)pPrPort)->lGParam4);
  473.  
  474.     BlockMove(pPrPort, printRecord->OtherPort, mostOfGrafPort);
  475.     SetPort(printRecord->OtherPort);
  476.     PicComment(kind, dataSize, dataHandle);
  477.     CallIdleProc(printRecord->idleProc);
  478.     SetPort(pPrPort);
  479. }
  480.  
  481. pascal short DraftPrTxMeas(short byteCount, Ptr textAddr,
  482.     Point *numer, Point *denom, FontInfo *info)
  483. {
  484.     short    retval;
  485.  
  486. #ifdef TRACKING
  487.     DebugStr("\pin DraftPrTxMeas;g");
  488. #endif
  489.  
  490.     // If the port is scaled, you'll need to modify the values
  491.     // passed to and returned by StdTxMeas() to take the
  492.     // scaling into account
  493.     retval = StdTxMeas(byteCount,textAddr,numer,denom,info);
  494.     return retval;
  495. }
  496.  
  497. #ifdef COMPRESSED_DATA
  498. pascal void DraftPrPix(PixMapPtr src, const Rect *srcRect, MatrixRecordPtr matrix,
  499.     short mode, RgnHandle mask, PixMapPtr matte, Rect *matteRect, short flags)
  500. {
  501. #pragma unused(src)
  502. #pragma unused(srcRect)
  503. #pragma unused(matrix)
  504. #pragma unused(mode)
  505. #pragma unused(mask)
  506. #pragma unused(matte)
  507. #pragma unused(matteRect)
  508. #pragma unused(flags)
  509.     // If we want to support sending compressed data, this is the
  510.     // place to hook in the support. See Develop 24, pp 72-83 for
  511.     // details. Also see IM:QuickTime pg 3-137 and IM:Imaging for
  512.     // more details. As an added benefit, CopyDeepMask comes through
  513.     // this proc, which is why the setIsPrintingFlag and
  514.     // clearIsPrintingFlag macros are commented out in the header
  515.     // file and point you to here for more explanation.
  516.     DebugStr("\pTsk. COMPRESSED_DATA flag set, but no code written.");
  517. }
  518. #endif
  519.  
  520. void SetPrgProcs(TPPrPort myPPrPort,Boolean usePicComments)
  521. {
  522.     ///// Instead of putting the procs in here, I should be
  523.     // using UPPs (shouldn't matter yet, since I'm only
  524.     // supporting 68K builds at the moment, but it's a
  525.     // future compatibility thing to note so when I do
  526.     // add PPC support, I don't forget)
  527.     myPPrPort->gProcs.textProc = DraftPrText;
  528.     myPPrPort->gProcs.lineProc = DraftPrLine;
  529.     myPPrPort->gProcs.rectProc = DraftPrRect;
  530.     myPPrPort->gProcs.rRectProc = DraftPrrRect;
  531.     myPPrPort->gProcs.ovalProc = DraftPrOval;
  532.     myPPrPort->gProcs.arcProc = DraftPrArc;
  533.     myPPrPort->gProcs.polyProc = DraftPrPoly;
  534.     myPPrPort->gProcs.rgnProc = DraftPrRgn;
  535.     myPPrPort->gProcs.bitsProc = DraftPrBits;
  536.     myPPrPort->gProcs.commentProc = DraftPrComment;
  537.     myPPrPort->gProcs.txMeasProc = DraftPrTxMeas;
  538.  
  539.     // note: no bottleneck replacement for getPicProc or putPicProc
  540.     
  541. #ifdef COMPRESSED_DATA
  542.     // If we want to handle compressed data, we put in our stdPix replacement
  543.     ((CGrafPort)(myPPrPort->gPort)).grafProcs->newProc1 = DraftPrPix;
  544. #endif
  545. }
  546.  
  547. pascal void ChangeBottleNeck(Boolean withColor, TPPrPort myPPrPort, MyPrintPtr thePrintPtr, Boolean withPicComments)
  548. {
  549.     if (withColor) {
  550.         OpenCPort((CGrafPtr)myPPrPort);
  551.         SetStdCProcs(&thePrintPtr->cProcs);
  552.         
  553.         // even with a Color PICT saving, we set the gProcs field of the Printing port 
  554.         // just in case some weird application wants to use them directly 
  555.         // to my knowledge, no application do such an absurd thing as that but Murphy Lives ! 
  556.         SetPrgProcs(myPPrPort,withPicComments);
  557.         
  558.         thePrintPtr->cProcs.textProc = DraftPrText;
  559.         thePrintPtr->cProcs.lineProc = DraftPrLine;
  560.         thePrintPtr->cProcs.rectProc = DraftPrRect;
  561.         thePrintPtr->cProcs.rRectProc = DraftPrrRect;
  562.         thePrintPtr->cProcs.ovalProc = DraftPrOval;
  563.         thePrintPtr->cProcs.arcProc = DraftPrArc;
  564.         thePrintPtr->cProcs.polyProc = DraftPrPoly;
  565.         thePrintPtr->cProcs.rgnProc = DraftPrRgn;
  566.         thePrintPtr->cProcs.bitsProc = DraftPrBits;
  567.         thePrintPtr->cProcs.commentProc = DraftPrComment;
  568.         thePrintPtr->cProcs.txMeasProc = DraftPrTxMeas;
  569. #ifdef COMPRESSED_DATA
  570.         // If we want to handle compressed data, we put in our stdPix replacement
  571.         ((CGrafPort)(myPPrPort->gPort)).grafProcs->newProc1 = DraftPrPix;
  572. #endif
  573.         ((CGrafPtr)myPPrPort)->grafProcs = &(thePrintPtr->cProcs);
  574.     } else {
  575.         OpenPort((GrafPtr)myPPrPort);
  576.         SetStdProcs(&myPPrPort->gProcs);
  577.         SetPrgProcs(myPPrPort,withPicComments);
  578.         myPPrPort->gPort.grafProcs = &myPPrPort->gProcs;
  579.     }
  580. }
  581.  
  582. pascal Boolean GetValues(MyPrintPtr thePrintPtr)
  583. {
  584.     StringHandle aStrHdl;
  585.  
  586.     aStrHdl = GetString(defaultFileNameID);
  587.     if (aStrHdl == NULL)
  588.         return false;
  589.     PStrcpy(thePrintPtr->fileName, *aStrHdl);
  590.  
  591.     return true;
  592. }
  593.  
  594. OSErr AskUser(MyPrintPtr thePrintPtr)
  595. {
  596.     Point    thePoint;
  597.     SFReply    theReply, *reply = &theReply;
  598.     OSErr    theError;
  599.     Str255    dummyString = "\pSelect output file";
  600.  
  601.     // using an initializer for a Point auto-variable makes global data
  602.     // when you're compiling with SC, so we need to do it this way.
  603.     // How incredibly brain-damaged. -DaveP
  604.     // Of course in a real driver, you'd never have this dialog, and if
  605.     // you did, you'd go to the effort to write the code to center the
  606.     // dialog, and you couldn't use an initializer, anyhow. It's still
  607.     // dain-bramaged what SC does. -DaveP
  608.  
  609.     thePoint.h = thePoint.v = 50;
  610.  
  611.     SFPutFile(thePoint, dummyString, thePrintPtr->fileName, 0, reply);
  612.     if (theReply.good) {
  613.         theError = FSDelete(theReply.fName, theReply.vRefNum);
  614.  
  615.         theError = Create(theReply.fName, theReply.vRefNum, 'RSED', 'rsrc');
  616.  
  617.         if (theError != noErr) 
  618.             return theError;
  619.  
  620.         theError = SetVol(NULL, theReply.vRefNum);
  621.         CreateResFile(theReply.fName);
  622.         thePrintPtr->fileRef = OpenResFile(theReply.fName);
  623.         if (thePrintPtr->fileRef == -1) 
  624.             theError = ResError();
  625.  
  626.         thePrintPtr->CurPage = 0;
  627.  
  628.         if (theError != noErr)
  629.             return theError;
  630.  
  631.         thePrintPtr->dirVol = theReply.vRefNum;
  632.         PStrcpy(thePrintPtr->fileName, (unsigned char *)(&(theReply.fName)));
  633.     } else theError = iPrAbort;
  634.  
  635.     return theError;
  636. }
  637.  
  638. pascal TPPrPort DraftPrOpenDoc(THPrint hPrint, TPPrPort pPrPort, Ptr pIOBuf)
  639. {
  640. #pragma unused(pIOBuf)
  641.  
  642.     SysEnvRec    theWorld;
  643.     Boolean        withPicComments;
  644.     OSErr        bugOutError;
  645.     TPPrPort    myPPrPort;
  646.     THPrint        *myHPrint;
  647.     MyPrintPtr    printRecord;
  648.  
  649. #ifdef TRACKING
  650.     DebugStr("\pin DraftPrOpenDoc;g");
  651. #endif
  652.  
  653.     myHPrint = &hPrint;
  654.     if (pPrPort == NULL) {    // does the caller give us a Printing Port or do we allocate it ? 
  655.         myPPrPort = (TPPrPort)NewPtr(sizeof(TPrPort));
  656.         if (myPPrPort == NULL) {
  657.             bugOutError = iMemFullErr;
  658.             goto BUGOUT;
  659.         }
  660.         myPPrPort->fOurPtr = true;
  661.     } else {
  662.         myPPrPort = pPrPort;
  663.         myPPrPort->fOurPtr = false;
  664.     }
  665.     myPPrPort->lGParam4 = (long) NewPtr(sizeof(MyPrintRec));    // we need this space to work
  666.     if (myPPrPort->lGParam4 == 0) {
  667.         bugOutError = iMemFullErr;
  668.         goto BUGOUT;
  669.     }
  670.     
  671.     withPicComments = (**hPrint).printX[9] == 0;
  672.     SysEnvirons(1, &theWorld);
  673.     
  674.     // the real job is here, changing the QuickDraw Bottleneck to install our printing routines 
  675.     ChangeBottleNeck(((theWorld.hasColorQD) && ((**hPrint).printX[8] == 0)),
  676.          myPPrPort, (MyPrintPtr)myPPrPort->lGParam4, withPicComments);
  677.     
  678.     // to prevent any real drawing, set the bounds to EmptyRect
  679.     if (IsColorGrafPort(&(myPPrPort->gPort))) {
  680.         CGrafPtr    thePort = (CGrafPtr)(&(myPPrPort->gPort));
  681.         Rect        *theRect = &((**(thePort->portPixMap)).bounds);
  682.         SetRect(theRect, 0, 0, 0, 0);
  683.     } else {
  684.         SetRect(&(myPPrPort->gPort.portBits.bounds), 0, 0, 0, 0);
  685.     }
  686.     myPPrPort->gPort.portRect = (**hPrint).prInfo.rPage;
  687.     
  688.     printRecord = (MyPrintPtr)(myPPrPort->lGParam4);
  689.     
  690.     if ((**hPrint).printX[6]) {
  691.         // just print specified range
  692.         printRecord->firstPage = (**hPrint).prJob.iFstPage;
  693.         printRecord->lastPage = (**hPrint).prJob.iLstPage;
  694.     } else {
  695.         // print all pages
  696.         printRecord->firstPage = 1;        // default
  697.         printRecord->lastPage = 9999;    // default
  698.     }
  699.  
  700.     if (!GetValues(printRecord)) {
  701.         bugOutError = iMemFullErr;
  702.         goto BUGOUT;
  703.     }
  704.     
  705.     printRecord->idleProc = (**hPrint).prJob.pIdleProc;
  706.  
  707.     printRecord->OtherPort = (GrafPtr)(NewPtr(sizeof(GrafPort)));
  708.     if (printRecord->OtherPort == NULL) {
  709.         bugOutError = iMemFullErr;
  710.         goto BUGOUT;
  711.     }
  712.     BlockMove(myPPrPort, printRecord, mostOfGrafPort);
  713.     
  714.     bugOutError = AskUser((MyPrintPtr)(myPPrPort->lGParam4));
  715.     if (bugOutError != noErr) {
  716.         goto BUGOUT;
  717.     }
  718.     
  719. // normal return
  720.     return myPPrPort;
  721.  
  722.  
  723. // error conditions make us come here
  724. BUGOUT:
  725.     if (myPPrPort != NULL) {
  726.         if (myPPrPort->lGParam4 != 0) {
  727.             if (!((*(*myHPrint))->printX[7] == 0)) {
  728.                 DisposPtr((Ptr)(printRecord->OtherPort));
  729.             }
  730.             DisposPtr((Ptr)printRecord);
  731.             if (IsColorGrafPort(&(myPPrPort->gPort)))
  732.                 CloseCPort((CGrafPtr)(myPPrPort));
  733.             else 
  734.                 ClosePort((GrafPtr)(myPPrPort));
  735.         }
  736.         if (myPPrPort->fOurPtr) 
  737.             DisposPtr((Ptr)(myPPrPort));
  738.     }
  739.     setPrintErr(bugOutError);
  740.     return 0L;
  741. }
  742.  
  743. pascal void DraftPrCloseDoc(TPPrPort pPrPort)
  744. {
  745. #ifdef TRACKING
  746.     DebugStr("\pin DraftPrCloseDoc;g");
  747. #endif
  748.  
  749.     if (pPrPort != NULL) {
  750.         if (pPrPort->lGParam4 != 0) {
  751.             MyPrintPtr    printRecord = (MyPrintPtr)(pPrPort->lGParam4);
  752.  
  753.             CloseResFile(printRecord->fileRef);
  754.             DisposPtr((Ptr)printRecord->OtherPort);
  755.             DisposPtr((Ptr)printRecord);
  756.         }
  757.  
  758.         if (IsColorGrafPort((GrafPtr)pPrPort))
  759.             CloseCPort((CGrafPtr)pPrPort);
  760.         else 
  761.             ClosePort((GrafPtr)pPrPort);
  762.         DisposPtr((Ptr)pPrPort);
  763.     }
  764. }
  765.  
  766. pascal void DraftPrOpenPage(TPPrPort pPrPort, TPRect pPageFrame)
  767. {
  768. #pragma unused(pPageFrame)
  769.     // in case of PICT saving, we create a new PICT file for each page 
  770.     // the name of the PICT file is the name chosen by the user + the
  771.     // number of the page and we store that file in the folder with the
  772.     // same name that we created in DraftPrOpenDoc 
  773.  
  774.     MyPrintPtr printRecord = (MyPrintPtr)pPrPort->lGParam4;
  775.  
  776. #ifdef TRACKING
  777.     DebugStr("\pin DraftPrOpenPage;g");
  778. #endif
  779.  
  780.     printRecord->CurPage++;
  781.  
  782.     setIsPrintingFlag();
  783.  
  784.     // let's reinitialize the picture saving grafport and open the picture for saving 
  785.     BlockMove(pPrPort, printRecord->OtherPort, mostOfGrafPort);
  786.     printRecord->OtherPort->picSave = NULL;
  787.     printRecord->OtherPort->rgnSave = NULL;
  788.     printRecord->OtherPort->polySave = NULL;
  789.     printRecord->OtherPort->grafProcs = NULL;
  790.     SetPort(printRecord->OtherPort);
  791.     // do scaling here
  792.     printRecord->thePict = OpenPicture(&printRecord->OtherPort->portRect);
  793.     if (printRecord->thePict == NULL) {
  794.         setPrintErr(iMemFullErr);
  795.         return;
  796.     }
  797.     ClipRect(&(printRecord->OtherPort->portRect));
  798.     SetPort((GrafPtr)pPrPort);
  799. }
  800.  
  801. static CTabHandle GetPmTable(CGrafPtr thePort)
  802. {
  803.     PixMapHandle thePixMap = thePort->portPixMap;
  804.     return((**thePixMap).pmTable);
  805. }
  806.  
  807. static Boolean IsInRange(short num, short min, short max)
  808. {
  809.     return ((num >= min) && (num <= max));
  810. }
  811.  
  812. pascal void DraftPrClosePage(TPPrPort pPrPort)
  813. {
  814.     // we also save the current color table as a 'clut' resource
  815.     // in the same file since a lot of Color Paint or Draw software
  816.     // use that kind of information to get the colors right
  817.  
  818.     long        theCount;
  819.     MyPrintPtr    printRecord = (MyPrintPtr)(pPrPort->lGParam4);
  820.     short        savedResFile;
  821.  
  822. #ifdef TRACKING
  823.     DebugStr("\pin DraftPrClosePage;g");
  824. #endif
  825.  
  826.     SetPort(printRecord->OtherPort);
  827.     ClosePicture();
  828.  
  829.     clearIsPrintingFlag();
  830.  
  831.     SetPort((GrafPtr)pPrPort);
  832.     if (IsInRange(printRecord->CurPage,printRecord->firstPage,printRecord->lastPage)) {
  833.         // this is initialized this way to work around a bug in SC 8.0.3
  834.         Str255    dummyString = "\pPage";
  835.  
  836.         // this'd be the place where we'd want to write out multiple copies
  837.         theCount = GetHandleSize((Handle)(printRecord->thePict));
  838.         savedResFile = CurResFile();
  839.         UseResFile(printRecord->fileRef);
  840.         AddResource((Handle)(printRecord->thePict), 'PICT', printRecord->CurPage, dummyString);
  841.         WriteResource((Handle)(printRecord->thePict));
  842.  
  843.         if (IsColorGrafPort((GrafPtr)pPrPort)) {
  844.             Handle    clutHandle;
  845.             Handle    tableHandle = (Handle) GetPmTable((CGrafPtr)pPrPort);
  846.             long    theCount = GetHandleSize(tableHandle);
  847.     
  848.             clutHandle = NewHandle(theCount);
  849.             if (clutHandle) {
  850.                 BlockMove(*tableHandle, *clutHandle, theCount);
  851.                 AddResource(clutHandle, 'clut', printRecord->CurPage, dummyString);
  852.                 WriteResource(clutHandle);
  853.             }
  854.         }
  855.     
  856.         UpdateResFile(printRecord->fileRef);
  857.         UseResFile(savedResFile);
  858.     } else {
  859.         DisposeHandle((Handle)(printRecord->thePict));
  860.     }
  861. }
  862.